<template>
    <div class="dimensions">        
        <div class="rows">
            <div class="name">行维度</div>
            <draggable v-model="metaLefts" group="site" animation="100" filter=".forbid" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                <transition-group>
                    <div v-for="(item,key) in metaLefts" :key="item.autoid">
                        <a-dropdown :trigger="['click']" :overlayClassName="'dimension-drop'">
                            <div :class="item.autoid===0?'item forbid':'item'">
                                {{item.showName}}（已选{{checkedCodes[item.codeName]?checkedCodes[item.codeName].length:0}}）
                                <a-icon type="caret-down" />
                            </div>
                            <div slot="overlay" @click.stop class="drop-list" v-if="item.autoid!==0">
                                <div class="dim-search" @click.stop>
                                    <a-input-search size="small" v-if="item.codeName!=='TIME'" @search="e=>{showSearch(e,item.codeName,item.showName)}" />
                                    <a-select placeholder="请选择" v-model="nearest" style="width:200px" @change="e=>{selectTime(e,'metaLefts')}" @click.stop v-if="item.codeName==='TIME'">
                                        <a-select-option :value="5">最近5年</a-select-option>
                                        <a-select-option :value="10">最近10年</a-select-option>
                                        <a-select-option :value="20">最近20年</a-select-option>
                                    </a-select>
                                </div>
                                <div class="drop-list-inner" @click.stop>
                                    <vue-scroll :ops="ops" style="height:100%">
                                        <a-tree
                                        checkable 
                                        :load-data="e=>{return onLoadData(e,item.codeName,'metaLefts',key)}" 
                                        :tree-data="item.objList"
                                        @check="e=>{checkNode(e,item.codeName)}"
                                        :defaultCheckedKeys="checkedCodes[item.codeName]"
                                        :v-model="checkedCodes[item.codeName]"
                                        :defaultExpandedKeys="expandedKeys[item.codeName]"
                                        :defaultExpandParent="true"
                                        :checkStrictly="true"
                                        :key="key+randomValue+'metaLefts'"
                                        @expand="(expandedKeys)=>{expandNode(expandedKeys,item.codeName)}"
                                        @select="e=>{selectNode(e,item.codeName)}"
                                        :replaceFields="replaceFields">
                                            <template #title="node">
                                                <a-dropdown :trigger="['contextmenu']">
                                                    <span>{{ node.dimName }}</span>
                                                    <template #overlay>
                                                    <a-menu @click="({key:menuKey}) => onContextMenuClick(menuKey,node,item.codeName,'metaLefts',key)">
                                                        <a-menu-item key="1">选择同级</a-menu-item>
                                                        <a-menu-item key="2">取消同级</a-menu-item>
                                                        <a-menu-item key="3" v-if="node.isParent">选择子项</a-menu-item>
                                                        <a-menu-item key="4" v-if="node.isParent">取消子项</a-menu-item>
                                                    </a-menu>
                                                    </template>
                                                </a-dropdown>
                                            </template>
                                        </a-tree>
                                    </vue-scroll>
                                </div>
                            </div>
                        </a-dropdown>
                    </div>
                </transition-group>
            </draggable>
        </div>
        <div class="columns">
            <div class="name">列维度</div>
            <draggable v-model="metaTops" group="site" animation="100" filter=".forbid" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                <transition-group>
                    <div v-for="(item,key) in metaTops" :key="item.autoid">
                        <a-dropdown :trigger="['click']" :overlayClassName="'dimension-drop'" >
                            <div :class="item.autoid===0?'item forbid':'item'">
                                {{item.showName}}（已选{{checkedCodes[item.codeName]?checkedCodes[item.codeName].length:0}}）
                                <a-icon type="caret-down" />
                            </div>
                            <div slot="overlay" @click.stop class="drop-list" v-if="item.autoid!==0">
                                <div class="dim-search" @click.stop>
                                    <a-input-search size="small" v-if="item.codeName!=='TIME'" @search="e=>{showSearch(e,item.codeName,item.showName)}" />
                                    <a-select style="width:200px" placeholder="请选择" v-model="nearest" @change="e=>{selectTime(e,'metaTops')}" @click.stop v-if="item.codeName==='TIME'">
                                        <a-select-option :value="5">最近5年</a-select-option>
                                        <a-select-option :value="10">最近10年</a-select-option>
                                        <a-select-option :value="20">最近20年</a-select-option>
                                    </a-select>
                                </div>
                                <div class="drop-list-inner" @click.stop>
                                    <vue-scroll :ops="ops" style="height:100%">
                                        <a-tree
                                        checkable 
                                        :load-data="e=>{return onLoadData(e,item.codeName,'metaTops',key)}" 
                                        :tree-data="item.objList"
                                        @check="e=>{checkNode(e,item.codeName)}"
                                        :defaultCheckedKeys="checkedCodes[item.codeName]"
                                        :v-model="checkedCodes[item.codeName]"
                                        :defaultExpandedKeys="expandedKeys[item.codeName]"
                                        :defaultExpandParent="true"
                                        :checkStrictly="true"
                                        :key="key+randomValue+'metaTops'"
                                        @expand="(expandedKeys)=>{expandNode(expandedKeys,item.codeName)}"
                                        @select="e=>{selectNode(e,item.codeName)}"
                                        :replaceFields="replaceFields">
                                            <template #title="node">
                                                <a-dropdown :trigger="['contextmenu']">
                                                    <span>{{ node.dimName }}</span>
                                                    <template #overlay>
                                                    <a-menu @click="({key:menuKey}) => onContextMenuClick(menuKey,node,item.codeName,'metaTops',key)">
                                                        <a-menu-item key="1">选择同级</a-menu-item>
                                                        <a-menu-item key="2">取消同级</a-menu-item>
                                                        <a-menu-item key="3" v-if="node.isParent">选择子项</a-menu-item>
                                                        <a-menu-item key="4" v-if="node.isParent">取消子项</a-menu-item>
                                                    </a-menu>
                                                    </template>
                                                </a-dropdown>
                                            </template>
                                        </a-tree>
                                    </vue-scroll>
                                </div>
                            </div>
                        </a-dropdown>
                    </div>
                </transition-group>
            </draggable>
        </div>
        <div class="fixed">
            <div class="name">固定维度
                <a-tooltip placement="left">
                    <template slot="title">
                    <span>固定维度的每个维度请选择一条数据，选择多条仅第一条有效</span>
                    </template>
                    <a-icon type="info-circle" theme="filled" />
                </a-tooltip>
            </div>
            <draggable v-model="fixeds" group="site" animation="100" filter=".forbid" dragClass="dragClass" ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                <transition-group>
                    <div v-for="(item,key) in fixeds" :key="item.autoid">
                        <a-dropdown :trigger="['click']" :overlayClassName="'dimension-drop'">
                            <div :class="item.autoid===0?'item forbid':'item'">
                                {{item.showName}}（已选{{checkedCodes[item.codeName]?checkedCodes[item.codeName].length:0}}）
                                <a-icon type="caret-down" />
                            </div>
                            <div slot="overlay" @click.stop class="drop-list" v-if="item.autoid!==0">
                                <div class="dim-search" @click.stop >
                                    <a-input-search size="small" v-if="item.codeName!=='TIME'" @search="e=>{showSearch(e,item.codeName,item.showName)}" />
                                </div>
                                <div class="drop-list-inner" @click.stop>
                                    <vue-scroll :ops="ops" style="height:100%">
                                    <a-tree 
                                        checkable 
                                        :load-data="e=>{return onLoadData(e,item.codeName,'fixeds',key)}" 
                                        :tree-data="item.objList"
                                        @check="e=>{checkNode(e,item.codeName)}"
                                        :defaultCheckedKeys="checkedCodes[item.codeName]"
                                        :v-model="checkedCodes[item.codeName]"
                                        :defaultExpandedKeys="expandedKeys[item.codeName]"
                                        :checkStrictly="true"
                                        :key="key+randomValue+'fixeds'"
                                        @expand="(expandedKeys)=>{expandNode(expandedKeys,item.codeName)}"
                                        @select="e=>{selectNode(e,item.codeName)}"
                                        :replaceFields="replaceFields" />
                                    </vue-scroll>
                                </div>
                            </div>
                        </a-dropdown>
                    </div>
                </transition-group>
            </draggable>
        </div>
        <a-modal v-model="visible" :title="'搜索'+searchModalName" @cancel="handleCancel" :footer="null" :width="800">
            <a-input-search v-model="searchKeyword" @search="showSearch(e,searchCodeName,searchModalName)" />
            <div class="search-tree-list">
                <a-tree 
                    checkable 
                    :tree-data="searchTreeList"
                    :v-model="checkedTreeKeys"
                    @check="checkSearchKeys"
                    :checkStrictly="true"
                    :key="searchTreeKey"
                    :defaultExpandAll="true"
                    :replaceFields="replaceFields" />
            </div>
            <div class="btns">
                <a-button type="primary" ghost @click="handleCancel">取消</a-button>
                <a-button type="primary" @click="handleOk">确定</a-button>
            </div>
        </a-modal>
    </div>
</template>

<script>
import draggable from 'vuedraggable';
import config from '../until/configs';
export default {
    name:'Dimensions',
    components: {
        draggable,
    },
    props:['dimData','cubeId','sheetId','isInput'],
    data() {
        return {
            drag: false,
            ops: config.vueScrollSetting,
            checkedCodes:{},
            expandedKeys:{},
            metaTopsNames:[],
            metaLeftsNames:[],
            fixedsNames:[],
            metaLefts: [
                { autoid: 0, dimensionName: '' },
            ],
            metaTops: [
                { autoid: 0, dimensionName: '' },
            ],
            fixeds: [
                { autoid: 0, dimensionName: '' }
            ],
            replaceFields:{title:'dimName',key:'dimCode',disabled:'chkDisabled'},
            visible:false,
            searchCodeName:'',
            searchKeyword:'',
            searchModalName:'',
            searchTreeList:[],
            checkedTreeKeys:[],
            searchTreeKey:0,
            randomValue:0,
            nearest:'请选择'
        }
    },
    watch:{
        cubeId(value) {
            if(value) {
                this.nearest = '请选择';
            }
        },
        dimData(value) {
            if(value) {
                this.randomValue = Math.random();
                this.checkedCodes = {};
                this.metaTopsNames = value.metaTops;
                this.metaLeftsNames = value.metaLefts;
                let metaLefts = [],metaTops = [],fixeds = [];   
                value.allDimensions.forEach(item=>{
                    this.checkedCodes[item.codeName] = value.checkedCodes[item.codeName]||[];
                });
                value.allDimensions.forEach((item)=>{
                    let index = value.metaLefts.indexOf(item.codeName);
                    if(index!==-1) {
                        item.index = index;
                        metaLefts.push(item);
                    }
                    let index2 = value.metaTops.indexOf(item.codeName);
                    if(index2!==-1) {
                        item.index = index2;
                        metaTops.push(item);
                    }
                    if(value.fixeds) {
                        let index3 = value.fixeds.indexOf(item.codeName);
                        if(index3!==-1) {
                            item.index = index3;
                            fixeds.push(item);
                        }
                        
                    }
                    item.objList.forEach(i=>{
                        if(!i.isParent) {
                            i.isLeaf = true;                            
                        }
                        if(!i.chkDisabled) {
                            i.disabled = true;
                        }
                        if(item.codeName==='TIME') {
                            if(i.children) {
                                i.children.forEach(node=>{
                                    if(!node.isParent) {
                                        node.isLeaf = true;
                                    }
                                })
                            }
                        }
                    })
                });
                metaLefts.sort(function(a,b){return a.index-b.index;});
                metaTops.sort(function(a,b){return a.index-b.index;});
                fixeds.sort(function(a,b){return a.index-b.index;});
                this.metaLefts = [{autoid:0,dimensionName:''},...metaLefts];                
                this.metaTops = [{autoid:0,dimensionName:''},...metaTops];
                this.fixeds = [{autoid:0,dimensionName:''},...fixeds];
            }
        }
    },
    methods: {
        metaSort(){

        },
        onStart() {
            this.drag = true;
        },
        onEnd() {
            this.drag = false;
            let metaLefts = [];
            this.metaLefts.forEach(item=>{
                if(item.id!==0&&item.codeName) {
                    metaLefts.push(item.codeName);
                }
            });
            let metaTops = [];
            this.metaTops.forEach(item=>{
                if(item.id!==0&&item.codeName) {
                    metaTops.push(item.codeName);
                }
            });
            let fixeds = [];
            this.fixeds.forEach(item=>{
                if(item.id!==0&&item.codeName) {
                    fixeds.push(item.codeName);
                    if(this.checkedCodes[item.codeName][0]) {
                        this.checkedCodes[item.codeName] = [this.checkedCodes[item.codeName][0]]
                    }                    
                }
            });
            this.metaLeftsNames = metaLefts;
            this.metaTopsNames = metaTops;
            this.fixedsNames = fixeds;
            let dimData = {
                metaLefts:metaLefts,
                metaTops:metaTops,
                fixeds:fixeds,
                allDimensions:this.dimData.allDimensions,
                checkedCodes:this.checkedCodes
            }
            this.$emit('dimensionDragEnd',dimData);
        },
        
        expandNode(expandedKeys,codeName) {
            this.expandedKeys[codeName] = expandedKeys;
        },

        onLoadData(treeNode,codeName,pos,key) {
            return new Promise(resolve => {
                if (treeNode.dataRef.children&&treeNode.dataRef.children.length>0) {
                    resolve();
                    return;
                }
                if(!this.expandedKeys[codeName]) {
                    this.expandedKeys[codeName] = [];
                }
                if(this.expandedKeys[codeName].indexOf(treeNode.eventKey)===-1) {
                    this.expandedKeys[codeName].push(treeNode.eventKey);
                }
                
                let params = {
                    parentCode:treeNode.eventKey,
                    cubeId:this.$props.cubeId,
                    dimType:codeName,
                    sheetId:this.$props.sheetId
                }
                if(this.isInput) {
                    params.isInput = 1;
                }
                return this.$http.getDimensionChildren(params).then(res=>{
                    res.dimensionList.forEach(item=>{
                        if(!item.isParent) {
                            item.isLeaf = true;
                        }
                        if(!item.chkDisabled) {
                            item.disabled = true;
                        }                        
                    });
                    let arr = this[pos][key].objList;
                    treeNode.dataRef.children = res.dimensionList;
                    this[pos][key].objList = [...arr];
                    resolve();
                })
            });            
        },

        checkNode(node,codeName) {
            this.checkedCodes[codeName] = node.checked;
            this.$emit('selectDimCode',this.checkedCodes);
        },
        selectNode(code,codeName) {
            let index  = this.checkedCodes[codeName].indexOf(code[0]);
            if(index===-1) {
                this.checkedCodes[codeName].push(code[0]);
            } else {
                this.checkedCodes[codeName].splice(index,1);
            }
            this.$emit('selectDimCode',this.checkedCodes);
        },

        onContextMenuClick(menuKey,node,codeName,pos,key) {
            if(!this.expandedKeys[codeName]) {
                this.expandedKeys[codeName] = [];
            }
            switch (menuKey) {
                case '1':
                case '2':
                    var treeList = [];
                    this[pos].some(item=>{
                        if(item.codeName===codeName) {
                            treeList = item.objList;
                        }
                    });
                    var pNode = null;
                    if(node.PARENT_ID) {
                        pNode = this.getPnodeByPid(treeList,node.PARENT_ID);
                    } else {
                        pNode = this.getPnode(treeList,node.eventKey);
                    }
                    
                    if(!pNode||node.eventKey===pNode.dimCode) {
                        if(menuKey==='1') {
                            treeList.forEach(item=>{
                                if(this.checkedCodes[codeName].indexOf(item.dimCode)===-1&&!item.disabled) {
                                    this.checkedCodes[codeName].push(item.dimCode);
                                }
                            });
                        } else {
                            treeList.forEach(item=>{
                                let index = this.checkedCodes[codeName].indexOf(item.dimCode);
                                if(index!==-1) {
                                    this.checkedCodes[codeName].splice(index,1);
                                }
                            });
                        }                
                                    
                    } else {
                        if(menuKey==='1') {
                            pNode.children.forEach(item=>{
                                if(this.checkedCodes[codeName].indexOf(item.dimCode)===-1&&!item.disabled) {
                                    this.checkedCodes[codeName].push(item.dimCode);
                                }
                            });
                        } else {
                            pNode.children.forEach(item=>{
                                let index = this.checkedCodes[codeName].indexOf(item.dimCode);
                                if(index!==-1) {
                                    this.checkedCodes[codeName].splice(index,1);
                                }
                            });
                        }    
                    }
                    this.$emit('selectDimCode',this.checkedCodes);
                    break;
                case '3':
                case '4':
                    node.expanded = true;
                    if(node.children) {
                        if(menuKey==='3') {
                            node.children.forEach(item=>{
                                let index = this.checkedCodes[codeName].indexOf(item.dimCode);
                                if(index===-1&&!item.disabled) {
                                    this.checkedCodes[codeName].push(item.dimCode);
                                }
                            })
                        } else {
                            node.children.forEach(item=>{
                                let index = this.checkedCodes[codeName].indexOf(item.dimCode);
                                if(index!==-1) {
                                    this.checkedCodes[codeName].splice(index,1);
                                }
                            })
                        }
                        this.$emit('selectDimCode',this.checkedCodes);
                        this[pos][key].objList = [...this[pos][key].objList];
                    } else {
                        this.onLoadData(node,codeName,pos,key).then(()=>{
                            if(node.dataRef.children) {
                                if(menuKey==='3') {
                                    node.dataRef.children.forEach(item=>{
                                        let index = this.checkedCodes[codeName].indexOf(item.dimCode);
                                        if(index===-1&&!item.disabled) {
                                            this.checkedCodes[codeName].push(item.dimCode);
                                        }
                                    })
                                } else {
                                    let codes = [];
                                    node.dataRef.children.forEach(item=>{
                                        if(!item.disabled) {
                                            codes.push(item.dimCode);
                                        }
                                    });
                                    let lastCodes = [];
                                    this.checkedCodes[codeName].forEach(item=>{
                                        if(codes.indexOf(item)===-1) {
                                            lastCodes.push(item);
                                        }
                                    })
                                    this.checkedCodes[codeName] = [...lastCodes];
                                }
                                this.$emit('selectDimCode',this.checkedCodes);
                            }
                        })
                    }
                    break;
                default:
                    break;
            }
            
        },

        getPnode(list,code,node) {
            let result = null;
            list.forEach(item=>{
                if(item.dimCode===code) {
                    result = node;
                } else {
                    if(item.children) {
                        result = this.getPnode(item.children,code,item);
                    }
                }
                
            });
            return result;
        },
        getPnodeByPid(list,pid) {
            let result = null;
            list.some(item=>{
                if(item.dimCode===pid) {
                    result = item;
                    return true;
                }
                if(item.children) {
                    this.getPnodeByPid(item.children,pid);
                }                
            });
            return result;
        },
        
        selectTime(e,pos) {
            var treeList = [];
            this.checkedCodes['TIME'] = [];
            this[pos].some(item=>{
                if(item.codeName==='TIME') {
                    treeList = item.objList;
                }
            });
            treeList.forEach(item=>{
                let index = this.checkedCodes['TIME'].indexOf(item.dimCode);
                if(index!==-1) {
                    this.checkedCodes['TIME'].splice(index,1);
                }
            });
            treeList.forEach((item,key)=>{
                if(key<e) {
                    if(item.children&&item.children.length>0) {
                        item.children.forEach(i=>{
                            let index =  this.checkedCodes['TIME'].indexOf(i.dimCode);
                            if(index===-1) {
                                this.checkedCodes['TIME'].push(i.dimCode);
                            }
                        })
                    } else {
                        let index =  this.checkedCodes['TIME'].indexOf(item.dimCode);
                        if(index===-1) {
                            this.checkedCodes['TIME'].push(item.dimCode);
                        }                        
                    }
                }
            });
            this.$emit('selectDimCode',this.checkedCodes);
        },
        showSearch(e,name,title) {
            this.searchKeyword = e;
            this.searchCodeName = name;
            this.searchModalName = title;
            this.visible = true;
            let params = {dimensionId:name,keyword:e,cubeId:this.cubeId}
            if(this.isInput) {
                params.isInput = 1;
            }
            this.$http.searhDimension(params).then(res=>{
                if(res&&res.dimensionList) {
                    this.searchTreeList = this.setDimTree(res.dimensionList,'-1',[]);
                    this.searchTreeKey = Math.random()
                }
            })
        },
        handleCancel() {
            this.visible = false;
            this.searchCodeName = '';
            this.searchKeyword = '';
            this.searchModalName = '';
            this.searchTreeList = [];
            this.searchTreeKey = 0;
            this.checkedTreeKeys = [];
        },
        handleOk() {
            let codeName = this.searchCodeName;
            if(!this.expandedKeys[codeName]) {
                this.expandedKeys[codeName] = [];
            }
            this.checkedTreeKeys.forEach(item=>{
                let index = this.checkedCodes[codeName].indexOf(item);
                if(index===-1) {
                    this.checkedCodes[codeName].push(item);
                }
            });
            this.$emit('selectDimCode',this.checkedCodes);
            this.handleCancel();
        },
        setDimTree(list,pid,arr) {
            list.forEach(item=>{
                if(item.PARENT_ID===pid) {
                    if(!item.children) {
                        item.children = [];
                    }
                    item.children = this.setDimTree(list,item.dimCode,item.children);
                    arr.push(item);
                }
            })
            return arr;
        },
        checkSearchKeys(e) {
            this.checkedTreeKeys = e.checked;
        }
    },
}
</script>
<style lang="scss">
.dimension-drop {
    border:1px solid #ccc;
    border-radius: 3px;
}
.drop-list-inner {
    .ant-tree-checkbox-disabled {
        display: none !important;
    }
    li.ant-tree-treenode-disabled > span:not(.ant-tree-switcher), 
    li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper, 
    li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper span {
        color:rgba($color: #000000, $alpha: 0.65);
        cursor: default;
    }
}


</style>
<style lang="scss" scoped>
    @import '../scss/dimensions.scss';
</style>